package controllers

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/inntu/backend/api/models"
	"github.com/inntu/backend/api/services"
	"github.com/inntu/backend/utils"
)

// ItemController 项目控制器
type ItemController struct {
	service *services.ItemService
}

// NewItemController 创建项目控制器
func NewItemController() *ItemController {
	return &ItemController{
		service: services.NewItemService(),
	}
}

// GetItems 获取项目列表
// @Summary 获取项目列表
// @Description 获取项目列表，支持按父项目、内容类型、状态筛选
// @Tags 项目管理
// @Accept json
// @Produce json
// @Param parent_id query int false "父项目ID"
// @Param content_type query string false "内容类型"
// @Param status query int false "状态"
// @Success 200 {object} utils.Response{data=[]models.Item}
// @Router /api/v1/items [get]
func (c *ItemController) GetItems(ctx *gin.Context) {
	parentIDStr := ctx.Query("parent_id")
	contentType := ctx.Query("content_type")
	statusStr := ctx.Query("status")

	var parentID *int
	if parentIDStr != "" {
		if id, err := strconv.Atoi(parentIDStr); err == nil {
			parentID = &id
		}
	}

	var status *int
	if statusStr != "" {
		if s, err := strconv.Atoi(statusStr); err == nil {
			status = &s
		}
	}

	items, err := c.service.GetItems(parentID, contentType, status)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "获取项目列表失败: "+err.Error())
		return
	}

	utils.SuccessResponse(ctx, "获取项目列表成功", items)
}

// GetItem 获取项目详情
// @Summary 获取项目详情
// @Description 获取项目详情
// @Tags 项目管理
// @Accept json
// @Produce json
// @Param id path int true "项目ID"
// @Success 200 {object} utils.Response{data=models.Item}
// @Router /api/v1/items/{id} [get]
func (c *ItemController) GetItem(ctx *gin.Context) {
	idStr := ctx.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	item, err := c.service.GetItem(id)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusNotFound, "项目不存在")
		return
	}

	utils.SuccessResponse(ctx, "获取项目详情成功", item)
}

// GetItemWithCategory 获取项目及其分类信息
// @Summary 获取项目及其分类信息
// @Description 获取项目详情及其关联的分类信息
// @Tags 项目管理
// @Accept json
// @Produce json
// @Param id path int true "项目ID"
// @Success 200 {object} utils.Response{data=models.Item}
// @Router /api/v1/items/{id}/category [get]
func (c *ItemController) GetItemWithCategory(ctx *gin.Context) {
	idStr := ctx.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	item, err := c.service.GetItemWithCategory(id)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusNotFound, "项目不存在")
		return
	}

	utils.SuccessResponse(ctx, "获取项目及分类成功", item)
}

// GetChildItems 获取子项目列表
// @Summary 获取子项目列表
// @Description 获取指定项目的子项目列表
// @Tags 项目管理
// @Accept json
// @Produce json
// @Param id path int true "父项目ID"
// @Success 200 {object} utils.Response{data=[]models.Item}
// @Router /api/v1/items/{id}/children [get]
func (c *ItemController) GetChildItems(ctx *gin.Context) {
	idStr := ctx.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	items, err := c.service.GetItems(&id, "", nil)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "获取子项目列表失败: "+err.Error())
		return
	}

	utils.SuccessResponse(ctx, "获取子项目列表成功", items)
}

// GetContentList 方法已移除（兼容旧版API）

// GetContent 方法已移除（兼容旧版API）

// UpdateContent 方法已移除（兼容旧版API）

// UploadContent 方法已移除（兼容旧版API）

// DeleteContent 方法已移除（兼容旧版API）

// GetContentById 方法已移除（兼容旧版API）

// CreateItem 创建项目（管理端）
// @Summary 创建项目（管理员）
// @Description 创建新的项目，支持JSON和multipart/form-data格式，multipart格式支持图标文件上传。需要管理员权限。
// @Tags 项目管理
// @Accept json,multipart/form-data
// @Produce json
// @Security Bearer
// @Param Authorization header string true "JWT认证token"
// @Param item body models.Item false "项目信息（JSON格式）"
// @Param name formData string false "项目名称（表单格式）"
// @Param description formData string false "项目描述（表单格式）"
// @Param content_type formData string false "内容类型（表单格式，默认markdown）"
// @Param api_endpoint formData string false "API端点（表单格式）"
// @Param page_path formData string false "页面路径（表单格式，页面类型项目无需设置）"
// @Param external_url formData string false "外部链接（表单格式）"
// @Param component_name formData string false "组件名称（表单格式）"
// @Param content formData string false "内容（表单格式，支持markdown）"
// @Param parent_id formData int false "父项目ID（表单格式）"
// @Param display_order formData int false "显示顺序（表单格式）"
// @Param is_small formData bool false "是否为小图标（表单格式）"
// @Param params formData string false "额外参数（表单格式）"
// @Param status formData int false "状态（表单格式）"
// @Param icon formData file false "图标文件（表单格式）"
// @Param icon_url formData string false "图标URL（表单格式，当没有上传文件时使用）"
// @Success 200 {object} utils.Response{data=models.Item}
// @Failure 401 {object} utils.Response "未授权访问"
// @Failure 403 {object} utils.Response "权限不足"
// @Router /api/v1/admin/items [post]
func (c *ItemController) CreateItem(ctx *gin.Context) {
	var item models.Item
	
	// 检查Content-Type来决定处理方式
	contentType := ctx.GetHeader("Content-Type")
	
	if strings.Contains(contentType, "multipart/form-data") {
		// 处理multipart/form-data格式（支持文件上传）
		
		// 获取基本字段
		item.Name = ctx.PostForm("name")
		if item.Name == "" {
			utils.ErrorResponse(ctx, http.StatusBadRequest, "项目名称不能为空")
			return
		}
		
		item.Description = getStringPointer(ctx.PostForm("description"))
		item.ContentType = ctx.PostForm("content_type")
		item.APIEndpoint = getStringPointer(ctx.PostForm("api_endpoint"))
		item.PagePath = getStringPointer(ctx.PostForm("page_path"))
		item.ExternalURL = getStringPointer(ctx.PostForm("external_url"))
		item.ComponentName = getStringPointer(ctx.PostForm("component_name"))
		item.Content = getStringPointer(ctx.PostForm("content"))
		// 处理 params 字段，确保是有效的 JSON
        if paramsStr := ctx.PostForm("params"); paramsStr != "" {
            item.Params = &paramsStr
        } else {
            // 如果 params 为空，设置为空的 JSON 对象
            emptyJSON := "{}"
            item.Params = &emptyJSON
        }
		
		// 解析数字字段
		if parentIDStr := ctx.PostForm("parent_id"); parentIDStr != "" {
			if parentID, err := strconv.Atoi(parentIDStr); err == nil {
				item.ParentID = &parentID
			}
		}
		
		// display_order字段已移除，使用默认值0
		item.DisplayOrder = 0
		
		if statusStr := ctx.PostForm("status"); statusStr != "" {
			if status, err := strconv.Atoi(statusStr); err == nil {
				item.Status = status
			} else {
				item.Status = 1 // 默认启用
			}
		} else {
			item.Status = 1 // 默认启用
		}
		
		// 解析布尔字段
		if isSmallStr := ctx.PostForm("is_small"); isSmallStr != "" {
			item.IsSmall, _ = strconv.ParseBool(isSmallStr)
		}
		
		// 处理图标文件上传
		file, header, err := ctx.Request.FormFile("icon")
		if err != nil && err != http.ErrMissingFile {
			utils.ErrorResponse(ctx, http.StatusBadRequest, "图标文件上传失败: "+err.Error())
			return
		}
		
		if file != nil {
			defer file.Close()
			
			// 验证文件类型
			fileContentType := header.Header.Get("Content-Type")
			filename := header.Filename
			
			// 如果Content-Type为空或不是图片类型，通过文件扩展名判断
			if fileContentType == "" || fileContentType == "application/octet-stream" {
				ext := strings.ToLower(filepath.Ext(filename))
				switch ext {
				case ".png":
					fileContentType = "image/png"
				case ".jpg", ".jpeg":
					fileContentType = "image/jpeg"
				case ".gif":
					fileContentType = "image/gif"
				case ".svg":
					fileContentType = "image/svg+xml"
				case ".webp":
					fileContentType = "image/webp"
				default:
					utils.ErrorResponse(ctx, http.StatusBadRequest, "不支持的文件类型，请上传图片文件（png, jpg, gif, svg, webp）")
					return
				}
			} else if !strings.HasPrefix(fileContentType, "image/") {
				utils.ErrorResponse(ctx, http.StatusBadRequest, "只支持图片文件")
				return
			}
			
			// 生成文件名
			newFilename := fmt.Sprintf("%d_%s", time.Now().Unix(), header.Filename)
			cosKey := fmt.Sprintf("icons/%s", newFilename)
			
			// 创建COS客户端
			cosClient, err := utils.NewCOSClient("zyx")
			if err != nil {
				utils.ErrorResponse(ctx, http.StatusInternalServerError, "COS客户端创建失败: "+err.Error())
				return
			}
			
			// 上传到COS
			uploadOpts := &utils.UploadOptions{
				ContentType: fileContentType,
				ACL:         "public-read",
			}
			
			err = cosClient.PutObject(context.Background(), cosKey, file, uploadOpts)
			if err != nil {
				utils.ErrorResponse(ctx, http.StatusInternalServerError, "图标上传失败: "+err.Error())
				return
			}
			
			// 生成COS URL
			item.Icon = fmt.Sprintf("https://ntu-1325732121.cos.ap-guangzhou.myqcloud.com/%s", cosKey)
			log.Printf("图标上传成功: %s -> %s", newFilename, item.Icon)
		} else {
			// 如果没有上传文件，使用从表单获取的图标URL
			if iconURL := ctx.PostForm("icon_url"); iconURL != "" {
				item.Icon = iconURL
			}
			// 注意：这里不强制要求图标，允许创建没有图标的项目
		}
		
		// 设置时间戳
		item.CreatedAt = time.Now()
		item.UpdatedAt = time.Now()
		
	} else {
		// 处理JSON格式
		if err := ctx.ShouldBindJSON(&item); err != nil {
			utils.ErrorResponse(ctx, http.StatusBadRequest, "请求参数错误: "+err.Error())
			return
		}
		
		// 处理 params 字段，确保是有效的 JSON
		if item.Params != nil && *item.Params == "" {
			// 如果 params 为空字符串，设置为空的 JSON 对象
			emptyJSON := "{}"
			item.Params = &emptyJSON
		} else if item.Params == nil {
			// 如果 params 为 nil，设置为空的 JSON 对象
			emptyJSON := "{}"
			item.Params = &emptyJSON
		}
	}

	// 创建项目
	if err := c.service.CreateItem(&item); err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "创建项目失败: "+err.Error())
		return
	}

	utils.SuccessResponse(ctx, "创建项目成功", item)
}



// getStringPointer 辅助函数：将字符串转换为指针，空字符串返回nil
func getStringPointer(s string) *string {
	if s == "" {
		return nil
	}
	return &s
}

// UpdateItem 更新项目（管理端）
// @Summary 更新项目（管理员）
// @Description 更新项目信息，支持JSON和multipart/form-data格式，multipart格式支持图标文件上传。需要管理员权限。
// @Tags 项目管理
// @Accept json,multipart/form-data
// @Produce json
// @Security Bearer
// @Param Authorization header string true "JWT认证token"
// @Param id path int true "项目ID"
// @Param item body models.Item false "项目信息（JSON格式）"
// @Param name formData string false "项目名称（表单格式）"
// @Param description formData string false "项目描述（表单格式）"
// @Param content_type formData string false "内容类型（表单格式）"
// @Param api_endpoint formData string false "API端点（表单格式）"
// @Param page_path formData string false "页面路径（表单格式）"
// @Param external_url formData string false "外部链接（表单格式）"
// @Param component_name formData string false "组件名称（表单格式）"
// @Param content formData string false "内容（表单格式）"
// @Param parent_id formData int false "父项目ID（表单格式）"
// @Param is_small formData bool false "是否为小图标（表单格式）"
// @Param params formData string false "额外参数（表单格式）"
// @Param status formData int false "状态（表单格式）"
// @Param icon formData file false "图标文件（表单格式）"
// @Param icon_url formData string false "图标URL（表单格式，当没有上传文件时使用）"
// @Success 200 {object} utils.Response{data=models.Item}
// @Failure 401 {object} utils.Response "未授权访问"
// @Failure 403 {object} utils.Response "权限不足"
// @Router /api/v1/admin/items/{id} [put]
func (c *ItemController) UpdateItem(ctx *gin.Context) {
	idStr := ctx.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	var item models.Item
	
	// 检查Content-Type来决定处理方式
	contentType := ctx.GetHeader("Content-Type")
	
	if strings.Contains(contentType, "multipart/form-data") {
		// 处理multipart/form-data格式（支持文件上传）
		
		// 获取基本字段
		item.Name = ctx.PostForm("name")
		if item.Name == "" {
			utils.ErrorResponse(ctx, http.StatusBadRequest, "项目名称不能为空")
			return
		}
		
		item.Description = getStringPointer(ctx.PostForm("description"))
		item.ContentType = ctx.PostForm("content_type")
		item.APIEndpoint = getStringPointer(ctx.PostForm("api_endpoint"))
		item.PagePath = getStringPointer(ctx.PostForm("page_path"))
		item.ExternalURL = getStringPointer(ctx.PostForm("external_url"))
		item.ComponentName = getStringPointer(ctx.PostForm("component_name"))
		item.Content = getStringPointer(ctx.PostForm("content"))
		// 处理 params 字段，确保是有效的 JSON
		if paramsStr := ctx.PostForm("params"); paramsStr != "" {
			item.Params = &paramsStr
		} else {
			// 如果 params 为空，设置为空的 JSON 对象
			emptyJSON := "{}"
			item.Params = &emptyJSON
		}
		
		// 解析数字字段
		if parentIDStr := ctx.PostForm("parent_id"); parentIDStr != "" {
			if parentID, err := strconv.Atoi(parentIDStr); err == nil {
				item.ParentID = &parentID
			}
		}
		
		// display_order字段已移除，使用默认值0
		item.DisplayOrder = 0
		
		if statusStr := ctx.PostForm("status"); statusStr != "" {
			if status, err := strconv.Atoi(statusStr); err == nil {
				item.Status = status
			} else {
				item.Status = 1 // 默认启用
			}
		} else {
			item.Status = 1 // 默认启用
		}
		
		// 解析布尔字段
		if isSmallStr := ctx.PostForm("is_small"); isSmallStr != "" {
			item.IsSmall, _ = strconv.ParseBool(isSmallStr)
		}
		
		// 处理图标文件上传
		file, header, err := ctx.Request.FormFile("icon")
		if err != nil && err != http.ErrMissingFile {
			utils.ErrorResponse(ctx, http.StatusBadRequest, "图标文件上传失败: "+err.Error())
			return
		}
		
		if file != nil {
			defer file.Close()
			
			// 验证文件类型
			fileContentType := header.Header.Get("Content-Type")
			filename := header.Filename
			
			// 如果Content-Type为空或不是图片类型，通过文件扩展名判断
			if fileContentType == "" || fileContentType == "application/octet-stream" {
				ext := strings.ToLower(filepath.Ext(filename))
				switch ext {
				case ".png":
					fileContentType = "image/png"
				case ".jpg", ".jpeg":
					fileContentType = "image/jpeg"
				case ".gif":
					fileContentType = "image/gif"
				case ".svg":
					fileContentType = "image/svg+xml"
				case ".webp":
					fileContentType = "image/webp"
				default:
					utils.ErrorResponse(ctx, http.StatusBadRequest, "不支持的文件类型，请上传图片文件（png, jpg, gif, svg, webp）")
					return
				}
			} else if !strings.HasPrefix(fileContentType, "image/") {
				utils.ErrorResponse(ctx, http.StatusBadRequest, "只支持图片文件")
				return
			}
			
			// 生成文件名
			newFilename := fmt.Sprintf("%d_%s", time.Now().Unix(), header.Filename)
			cosKey := fmt.Sprintf("icons/%s", newFilename)
			
			// 创建COS客户端
			cosClient, err := utils.NewCOSClient("zyx")
			if err != nil {
				utils.ErrorResponse(ctx, http.StatusInternalServerError, "COS客户端创建失败: "+err.Error())
				return
			}
			
			// 上传到COS
			uploadOpts := &utils.UploadOptions{
				ContentType: fileContentType,
				ACL:         "public-read",
			}
			
			err = cosClient.PutObject(context.Background(), cosKey, file, uploadOpts)
			if err != nil {
				utils.ErrorResponse(ctx, http.StatusInternalServerError, "图标上传失败: "+err.Error())
				return
			}
			
			// 生成COS URL
			item.Icon = fmt.Sprintf("https://ntu-1325732121.cos.ap-guangzhou.myqcloud.com/%s", cosKey)
			log.Printf("图标上传成功: %s -> %s", newFilename, item.Icon)
		} else {
			// 如果没有上传文件，使用从表单获取的图标URL
			if iconURL := ctx.PostForm("icon_url"); iconURL != "" {
				item.Icon = iconURL
			}
			// 注意：这里不强制要求图标，允许更新时不修改图标
		}
		
		// 设置更新时间戳
		item.UpdatedAt = time.Now()
		
	} else {
		// 处理JSON格式
		if err := ctx.ShouldBindJSON(&item); err != nil {
			utils.ErrorResponse(ctx, http.StatusBadRequest, "请求参数错误: "+err.Error())
			return
		}
		
		// 处理 params 字段，确保是有效的 JSON
		if item.Params != nil && *item.Params == "" {
			// 如果 params 为空字符串，设置为空的 JSON 对象
			emptyJSON := "{}"
			item.Params = &emptyJSON
		} else if item.Params == nil {
			// 如果 params 为 nil，设置为空的 JSON 对象
			emptyJSON := "{}"
			item.Params = &emptyJSON
		}
	}

	item.ID = id
	if err := c.service.UpdateItem(&item); err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "更新项目失败: "+err.Error())
		return
	}

	utils.SuccessResponse(ctx, "更新项目成功", item)
}

// DeleteItem 删除项目（管理端）
// @Summary 删除项目（管理员）
// @Description 逻辑删除项目。需要管理员权限。
// @Tags 项目管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param Authorization header string true "JWT认证token"
// @Param id path int true "项目ID"
// @Success 200 {object} utils.Response
// @Failure 401 {object} utils.Response "未授权访问"
// @Failure 403 {object} utils.Response "权限不足"
// @Router /api/v1/admin/items/{id} [delete]
func (c *ItemController) DeleteItem(ctx *gin.Context) {
	idStr := ctx.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	if err := c.service.DeleteItem(id); err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "删除项目失败: "+err.Error())
		return
	}

	utils.SuccessResponse(ctx, "删除项目成功", map[string]interface{}{"deleted": true})
}

// ===== 页面项目关联关系管理 API =====

// GetItemWithRelatedItems 获取页面项目及其关联的项目
// @Summary 获取页面项目及其关联的项目
// @Description 获取页面类型项目及其关联的所有项目
// @Tags 页面项目关联
// @Accept json
// @Produce json
// @Param id path int true "页面项目ID"
// @Success 200 {object} utils.Response{data=models.Item}
// @Router /api/v1/items/{id}/related [get]
func (c *ItemController) GetItemWithRelatedItems(ctx *gin.Context) {
	idStr := ctx.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	item, err := c.service.GetItemWithRelatedItems(id)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusNotFound, "项目不存在")
		return
	}

	utils.SuccessResponse(ctx, "获取页面项目关联成功", item)
}

// AddItemToPageItem 将项目添加到页面项目的关联中
// @Summary 添加项目到页面项目关联
// @Description 将指定项目添加到页面类型项目的关联中
// @Tags 页面项目关联
// @Accept json
// @Produce json
// @Param page_item_id path int true "页面项目ID"
// @Param item_id path int true "关联项目ID"
// @Param display_order query int false "显示顺序"
// @Success 200 {object} utils.Response
// @Router /api/v1/items/{page_item_id}/related/{item_id} [post]
func (c *ItemController) AddItemToPageItem(ctx *gin.Context) {
	pageItemIDStr := ctx.Param("page_item_id")
	itemIDStr := ctx.Param("item_id")
	displayOrderStr := ctx.DefaultQuery("display_order", "0")

	pageItemID, err := strconv.Atoi(pageItemIDStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的页面项目ID")
		return
	}

	itemID, err := strconv.Atoi(itemIDStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	displayOrder, err := strconv.Atoi(displayOrderStr)
	if err != nil {
		displayOrder = 0
	}

	if err := c.service.AddItemToPageItem(pageItemID, itemID, displayOrder); err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "添加关联失败: "+err.Error())
		return
	}

	utils.SuccessResponse(ctx, "添加关联成功", map[string]interface{}{
		"page_item_id": pageItemID,
		"item_id":      itemID,
		"display_order": displayOrder,
	})
}

// RemoveItemFromPageItem 从页面项目的关联中移除项目
// @Summary 从页面项目关联中移除项目
// @Description 从页面类型项目的关联中移除指定项目
// @Tags 页面项目关联
// @Accept json
// @Produce json
// @Param page_item_id path int true "页面项目ID"
// @Param item_id path int true "关联项目ID"
// @Success 200 {object} utils.Response
// @Router /api/v1/items/{page_item_id}/related/{item_id} [delete]
func (c *ItemController) RemoveItemFromPageItem(ctx *gin.Context) {
	pageItemIDStr := ctx.Param("page_item_id")
	itemIDStr := ctx.Param("item_id")

	pageItemID, err := strconv.Atoi(pageItemIDStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的页面项目ID")
		return
	}

	itemID, err := strconv.Atoi(itemIDStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	if err := c.service.RemoveItemFromPageItem(pageItemID, itemID); err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "移除关联失败: "+err.Error())
		return
	}

	utils.SuccessResponse(ctx, "移除关联成功", map[string]interface{}{
		"page_item_id": pageItemID,
		"item_id":      itemID,
	})
}

// GetPageItemRelations 获取页面项目的所有关联关系
// @Summary 获取页面项目的关联关系
// @Description 获取页面类型项目关联的所有项目列表
// @Tags 页面项目关联
// @Accept json
// @Produce json
// @Param id path int true "页面项目ID"
// @Success 200 {object} utils.Response{data=[]models.Item}
// @Router /api/v1/items/{id}/relations [get]
func (c *ItemController) GetPageItemRelations(ctx *gin.Context) {
	idStr := ctx.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	items, err := c.service.GetPageItemRelations(id)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "获取关联关系失败: "+err.Error())
		return
	}

	utils.SuccessResponse(ctx, "获取关联关系成功", items)
}

// UpdatePageItemRelationOrder 更新页面项目关联的显示顺序
// @Summary 更新页面项目关联的显示顺序
// @Description 更新页面类型项目与关联项目的显示顺序
// @Tags 页面项目关联
// @Accept json
// @Produce json
// @Param page_item_id path int true "页面项目ID"
// @Param item_id path int true "关联项目ID"
// @Param display_order query int true "显示顺序"
// @Success 200 {object} utils.Response
// @Router /api/v1/items/{page_item_id}/related/{item_id}/order [put]
func (c *ItemController) UpdatePageItemRelationOrder(ctx *gin.Context) {
	pageItemIDStr := ctx.Param("page_item_id")
	itemIDStr := ctx.Param("item_id")
	displayOrderStr := ctx.Query("display_order")

	pageItemID, err := strconv.Atoi(pageItemIDStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的页面项目ID")
		return
	}

	itemID, err := strconv.Atoi(itemIDStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的项目ID")
		return
	}

	displayOrder, err := strconv.Atoi(displayOrderStr)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "无效的显示顺序")
		return
	}

	if err := c.service.UpdatePageItemRelationOrder(pageItemID, itemID, displayOrder); err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "更新显示顺序失败: "+err.Error())
		return
	}

	utils.SuccessResponse(ctx, "更新显示顺序成功", map[string]interface{}{
		"page_item_id":  pageItemID,
		"item_id":       itemID,
		"display_order": displayOrder,
	})
}
